package org.az.netty_study.p09_netty组件之ByteBuf;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;

import static org.az.netty_study.ByteBufferUtil.logBuf;

/**
 * 往ByteBuf写入数据的方法，几乎都已以write开头
 * 比如写入字节，就是writeByte(int)，写入字符，就是就是writeChar(int)，以此类推
 */
public class _3_ByteBuf读写 {
    public static void main(String[] args) {
        /**
         * 写入字节数组
         * 由于没有读取，只有写入，此时读指针是0，写指针是11
         */
        ByteBuf buf = ByteBufAllocator.DEFAULT.buffer(16);
        buf.writeBytes("hello world".getBytes());
        logBuf(buf);

        /**
         * 写入int，这里是大端写入，写入的是00 00 00 01，共4个字节
         * 此时读指针是0，写指针是15
         */
        buf.writeInt(1);
        logBuf(buf);

        /**
         * 再写一个char，此时会发生扩容
         * 一个A字符它会用两个字节来表示，00 41
         */
        buf.writeChar('A');
        logBuf(buf);

        /**
         * 读取的方法，以read开头，比如读取一个int数据，就是readInt,这系列方法会改变读指针
         * 读取一个byte(16进制的68就是十进制的104)
         * 读取多少个字节，读指针就往后移动多少，读指针前面的字节就成了废弃字节
         * 此时读指针是1，写指针是17，读指针前面的字节(区间在[0, 1))就成了废弃字节
         * 此时再统计ByteBuf内的数据，就是下标区间在[1, 17]范围内的字节
         */
        System.out.println(buf.readByte());
        logBuf(buf);

        /**
         * 重复读
         * 跟nio一样，如果想重复读应该怎么办呢?
         * 在操作之前做一个mark标记，记录下此时读指针位置，再调用rest就能恢复到之前记录是的状态，跟nio类似
         * 只不过mark标记，可以分为读指针的mark和写指针的mark，reset也分为读指针的reset和写指针的reset
         */
        buf.markReaderIndex();
        System.out.println(buf.readByte());
        buf.resetReaderIndex();
        //发现读数据后，这里打印的ByteBuf内部结果跟读取之前一样，所以reset生效了
        logBuf(buf);
        /**
         * 根nio一样，ByteBuf也可以直接根据索引读取
         * 这些方法以get开头，这种方法不会改变读指针
         * buf.getByte(0)，表示从索引0开始，往后读取一个int数据，也就是4字节数据
         * 这种方法可以直接读取到废弃的字节，比如下面就读取到了104
         */
        System.out.println(buf.getByte(0));
    }
}
